package com.kusen.jmm;

import java.util.ArrayList;
import java.util.List;

/**
 * java内存模型
 * JMM是java内存模型一种简称
 * 概率：java存储的数据是在物理内存也就是电脑的主内存，但是线程需要操作主内存的东西就要将主内存中的数据复制一份到自己的工作内存中来
 * 因为线程跟线程之间不能过横线的扩展。所以线程操作数据完之后必须是要重新写入主内存中去让其他线程去操作的数据时需要判断该数据是否
 * 已经被修改过
 * 关键字：使用volatile可以是线程之间可以有可见性
 * <p>
 * 内存模型的几种特性：1.原则性、2.可见性
 * <p>
 * 演示案例 :
 * 1.线程之间没有横向通知
 * 2.使用volatile关键字
 */
//资源类
//高内聚，低偶和
class MyNumber {
    volatile int number = 10;

    public void update() {
        this.number = 1024;
    }
}

public class JmmTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //线程操作资源类 创建资源类
        MyNumber myNumber = new MyNumber();
        //创建2个线程 一个是A线程和一个主线程Main
        new Thread(() -> {
            try {
                Thread.sleep(3000);//这里睡了3秒，其他线程会先抢到cpu资源
                myNumber.update();//改变资源类中的数据
                System.out.println(Thread.currentThread().getName() + "：update number ,number value：" + myNumber.number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "AAA").start();
        while (myNumber.number == 10) {//while方法也可以用来判断，可以用来防止线程虚假唤醒
            //如果各个线程拷贝数据到工作区间，那么这个数据在其他线程改变但是我自己又独有一份数据，这时就会进入死循环
            //就可以验证java的内存模型是线程操作数据时是将数据拷贝到自己的工作内存中的
        }
        System.out.println(Thread.currentThread().getName() + "：come out to ....");//验证最后线程退出
    }
}
